package com.tanhua.server.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.api.VisitorsApi;
import com.tanhua.dubbo.server.pojo.PageInfo;
import com.tanhua.dubbo.server.pojo.Publish;
import com.tanhua.dubbo.server.pojo.Visitors;
import com.tanhua.server.pojo.User;
import com.tanhua.server.pojo.UserInfo;
import com.tanhua.server.utils.RelativeDateFormat;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.Movements;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.PicUploadResult;
import com.tanhua.server.vo.VisitorsVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @author: Administrator
 * @date: Created in 2021/2/20 18:43
 * @version: 0.0.1
 * @modified By:
 */
@Service
public class MovementsService {
    @Autowired
    private PicUploadService picUploadService;
    @Reference(version = "1.0.0")
    private QuanZiApi quanZiApi;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private RedisTemplate<String,String>redisTemplate;

    @Reference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    public String saveMovements(String textContent, MultipartFile[]imageContent, String location, String longitude, String latitude) {
        User user = UserThreadLocal.get();
        Publish publish=new Publish();
        publish.setUserId(user.getId());
        publish.setText(textContent);
        publish.setLocationName(location);
        publish.setLongitude(longitude);
        publish.setLatitude(latitude);
        publish.setSeeType(1);
        //图片上传
        List<String>picUrls=new ArrayList<>();
        for (MultipartFile file : imageContent) {
            PicUploadResult picUploadResult = this.picUploadService.upload(file);
            picUrls.add(picUploadResult.getName());
        }
        publish.setMedias(picUrls);
        return this.quanZiApi.savePublish(publish);
    }

    private PageResult queryPublishList(User user,Integer page, Integer pageSize) {
        PageResult pageResult=new PageResult();
        Long userId=null; //默认查询推荐动态
        PageInfo<Publish>pageInfo=null;
        if(null==user){
            //查询推荐动态
            String key="QUANZI_PUBLISH_RECOMMEND_"+UserThreadLocal.get().getId();
            String value = this.redisTemplate.opsForValue().get(key);
            if(StringUtils.isNotEmpty(value)){
                //命中了数据
                String[] pids = StringUtils.split(value, ",");
                int startIndex=(page-1)*pageSize;
                if(startIndex<pids.length){
                    int endIndex=startIndex+pageSize-1;
                    if(endIndex>=pids.length){
                        endIndex=pids.length-1;
                    }
                    List<Long>pidList=new ArrayList<>();
                    for(int i=startIndex;i<=endIndex;i++){
                       pidList.add(Long.valueOf(pids[i]));
                    }
                   List<Publish>publishList= this.quanZiApi.queryPublishByPids(pidList);
                    pageInfo=new PageInfo<>();
                    pageInfo.setRecords(publishList);
                }
            }
        }
        if(pageInfo==null){
            if(null!=user){ //查询好友动态
                userId=user.getId();
            }
           pageInfo = this.quanZiApi.queryPublishList(userId, page, pageSize);
        }

        user=UserThreadLocal.get();//查询完成后，依然还是需要获取到当前的登录用户
        pageResult.setCounts(0);
        pageResult.setPages(0);
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        List<Publish> records = pageInfo.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return pageResult;
        }
        List<Movements>movementsList=new ArrayList<>();
        List<Long>userIds=new ArrayList<>();
        for (Publish record : records) {
            Movements movements=new Movements();
            movements.setId(record.getId().toHexString());
            String likeUserKey="QUANZI_COMMENT_LIKE_USER_"+user.getId()+"_"+movements.getId();
            movements.setHasLiked(this.redisTemplate.hasKey(likeUserKey)?1:0); //是否点赞
            String likeCommentKey="QUANZI_LIKE_COMMENT_"+movements.getId();
            String value=this.redisTemplate.opsForValue().get(likeCommentKey);
            if(StringUtils.isNotEmpty(value)){
                movements.setLikeCount(Integer.valueOf(value)); //点赞数
            }else{
                movements.setLikeCount(0);
            }
            String loveUserKey="QUANZI_COMMENT_LOVE_USER_"+user.getId()+"_"+movements.getId();
            movements.setHasLoved(this.redisTemplate.hasKey(loveUserKey)?1:0); // 是否喜欢
            String loveCommentKey="QUANZI_LOVE_COMMENT_"+movements.getId();
            String value2=this.redisTemplate.opsForValue().get(loveCommentKey);
            if(StringUtils.isNotEmpty(value2)){
                movements.setLoveCount(Integer.valueOf(value2)); // 喜欢数
            }else{
                movements.setLoveCount(0);
            }
            movements.setDistance("1.2公里");//TODO 距离
            movements.setUserId(record.getUserId());
            if(!userIds.contains(record.getUserId())){
                userIds.add(record.getUserId());
            }
            movements.setCommentCount(30); //TODO 评论数
            movements.setCreateDate(RelativeDateFormat.format(new Date(record.getCreated()))); //发布时间，10分钟前
            movements.setImageContent(record.getMedias().toArray(new String[]{}));
            movements.setTextContent(record.getText());
            movementsList.add(movements);
        }
        QueryWrapper<UserInfo>queryWrapper=new QueryWrapper<>();
        queryWrapper.in("user_id",userIds);
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);
        for (Movements movements : movementsList) {
          for (UserInfo userInfo : userInfoList) {
                if(userInfo.getUserId().longValue()==movements.getUserId().longValue()){
                    movements.setAge(userInfo.getAge());
                    movements.setAvatar(userInfo.getLogo());
                    movements.setGender(userInfo.getSex().name().toLowerCase());
                    movements.setNickname(userInfo.getNickName());
                    movements.setTags(StringUtils.split(userInfo.getTags(),","));
                    break;
                }
            }
        }
        pageResult.setItems(movementsList);
        return pageResult;
    }

    public PageResult queryRecommendPublishList(Integer page, Integer pageSize) {
        return this.queryPublishList(null,page,pageSize);
    }

    public PageResult queryUsePublishList(Integer page, Integer pageSize) {
        return this.queryPublishList(UserThreadLocal.get(),page,pageSize);
    }
    /**
     * @description 点赞
     * @author
     * @date
     * @param
     *@return
     */
    public Long likeComment(String publishId) {
        User user=UserThreadLocal.get();
        boolean bool = this.quanZiApi.saveLikeComment(user.getId(), publishId);
        if(!bool){
            return null;
        }
        long likeCount=0L;
        //保存点赞数到redis
        String likeCommentKey="QUANZI_LIKE_COMMENT_"+publishId;
        if(!this.redisTemplate.hasKey(likeCommentKey)){
            Long likeCommentCount = this.quanZiApi.queryCommentCount(publishId, 1);
            likeCount=likeCommentCount;
            this.redisTemplate.opsForValue().set(likeCommentKey,String.valueOf(likeCount));
        }else{
            likeCount=this.redisTemplate.opsForValue().increment(likeCommentKey);
        }
        //记录已点赞
        String likeUserKey="QUANZI_COMMENT_LIKE_USER_"+user.getId()+"_"+publishId;
        this.redisTemplate.opsForValue().set(likeUserKey,"1");
        return likeCount;
    }
    /**
     * @description 取消点赞
     * @author
     * @date
     * @param
     *@return
     */
    public Long disLikeComment(String publishId) {
        User user=UserThreadLocal.get();
        boolean bool = this.quanZiApi.removeLikeComment(user.getId(), publishId, 1);
        if(!bool){
            return null;
        }
        //redis中点赞数-1
        String likeCommentKey="QUANZI_LIKE_COMMENT_"+publishId;
        Long count = this.redisTemplate.opsForValue().decrement(likeCommentKey);
        //取消用户的点赞记录
        String likeUserKey="QUANZI_COMMENT_LIKE_USER_"+user.getId()+"_"+publishId;
        this.redisTemplate.delete(likeUserKey);
        return count;
    }
    /**
     * @description 喜欢
     * @author
     * @date
     * @param
     *@return
     */
    public Long loveComment(String publishId) {
        User user=UserThreadLocal.get();
        boolean bool = this.quanZiApi.saveLoveComment(user.getId(),publishId);
        if(!bool){
            return null;
        }
        long loveCount=0L;
        //保存喜欢数到redis
        String loveCommentKey="QUANZI_LOVE_COMMENT_"+publishId;
        if(!this.redisTemplate.hasKey(loveCommentKey)){
            Long loveCommentCount = this.quanZiApi.queryCommentCount(publishId, 3);
            loveCount=loveCommentCount;
            this.redisTemplate.opsForValue().set(loveCommentKey,String.valueOf(loveCount));
        }else{
            loveCount=this.redisTemplate.opsForValue().increment(loveCommentKey);
        }
        //记录已喜欢
        String loveUserKey="QUANZI_COMMENT_LOVE_USER_"+user.getId()+"_"+publishId;
        this.redisTemplate.opsForValue().set(loveUserKey,"1");
        return loveCount;
    }
    /**
     * @description 取消喜欢
     * @author
     * @date
     * @param
     *@return
     */
    public Long unLoveComment(String publishId) {
        User user=UserThreadLocal.get();
        boolean bool = this.quanZiApi.removeLikeComment(user.getId(),publishId,3);
        if(!bool){
            return null;
        }
        //redis中喜欢数-1
        String loveCommentKey="QUANZI_LOVE_COMMENT_"+publishId;
        Long count = this.redisTemplate.opsForValue().decrement(loveCommentKey);
        //取消用户的喜欢记录
        String loveUserKey="QUANZI_COMMENT_LOVE_USER_"+user.getId()+"_"+publishId;
        this.redisTemplate.delete(loveUserKey);
        return count;
    }

    public Movements queryMovementsById(String publishId) {
        Publish publish = this.quanZiApi.queryPublishById(publishId);
        if(null==publish){
            return null;
        }
        Movements movements=new Movements();
        movements.setId(publish.getId().toHexString());
        movements.setImageContent(publish.getMedias().toArray(new String[]{}));
        movements.setTextContent(publish.getText());
        movements.setUserId(publish.getUserId());
        movements.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
        UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(publish.getUserId());
        if(null==userInfo){
            return null;
        }
        this.fillValueToMovements(movements,userInfo);
        return movements;
    }

    private void fillValueToMovements(Movements movements,UserInfo userInfo){
        User user=UserThreadLocal.get();
        movements.setAge(userInfo.getAge());
        movements.setAvatar(userInfo.getLogo());
        movements.setGender(userInfo.getSex().name().toLowerCase());
        movements.setNickname(userInfo.getNickName());
        movements.setTags(StringUtils.split(userInfo.getTags(),','));
        Long commentCount = this.quanZiApi.queryCommentCount(movements.getId(), 2);
        if(null==commentCount){
            movements.setCommentCount(0);
        }else{
            movements.setCommentCount(commentCount.intValue());
        }
        movements.setDistance("1.2公里");//TODO 距离
        String likeUserKey="QUANZI_COMMENT_LIKE_USER_"+user.getId()+"_"+movements.getId();
        movements.setHasLiked(this.redisTemplate.hasKey(likeUserKey)?1:0); //是否点赞
        String likeCommentKey="QUANZI_LIKE_COMMENT_"+movements.getId();
        String value=this.redisTemplate.opsForValue().get(likeCommentKey);
        if(StringUtils.isNotEmpty(value)){
            movements.setLikeCount(Integer.valueOf(value)); //点赞数
        }else{
            movements.setLikeCount(0);
        }
        String loveUserKey="QUANZI_COMMENT_LOVE_USER_"+user.getId()+"_"+movements.getId();
        movements.setHasLoved(this.redisTemplate.hasKey(loveUserKey)?1:0); // 是否喜欢
        String loveCommentKey="QUANZI_LOVE_COMMENT_"+movements.getId();
        String value2=this.redisTemplate.opsForValue().get(loveCommentKey);
        if(StringUtils.isNotEmpty(value2)){
            movements.setLoveCount(Integer.valueOf(value2)); // 喜欢数
        }else{
            movements.setLoveCount(0);
        }
    }

    public List<VisitorsVo> queryVisitorsList() {
        User user=UserThreadLocal.get();
        //如果redis中存在s上一次查询的时间点的话就按照时间查询，否则就按照数量查询
        String redisKey="visitors_"+user.getId();
        String data = this.redisTemplate.opsForValue().get(redisKey);
        List<Visitors> visitors=null;
        if(StringUtils.isEmpty(data)){
            //按照数量查询
            this.redisTemplate.opsForValue().set(redisKey,System.currentTimeMillis()+"");
            visitors=this.visitorsApi.topVisitor(user.getId(),6);
        }else{
            //按照时间查询
             visitors=this.visitorsApi.topVisitor(user.getId(), Long.valueOf(data));
        }
        if(CollectionUtils.isEmpty(visitors)){
            return Collections.emptyList();
        }
        List<Long>ids=new ArrayList<>();
        for (Visitors visitor : visitors) {
            if(!ids.contains(visitor.getVisitorUserId())){
                ids.add(visitor.getVisitorUserId());
            }
        }
        QueryWrapper<UserInfo>queryWrapper=new QueryWrapper<>();
        queryWrapper.in("user_id",ids);
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);
        List<VisitorsVo>visitorsVoList=new ArrayList<>();
        for (Visitors visitor : visitors) {
            for (UserInfo userInfo : userInfoList) {
                if(visitor.getVisitorUserId().longValue()==userInfo.getUserId().longValue()){
                    VisitorsVo visitorsVo=new VisitorsVo();
                    visitorsVo.setId(userInfo.getUserId());
                    visitorsVo.setAge(userInfo.getAge());
                    visitorsVo.setAvatar(userInfo.getLogo());
                    visitorsVo.setFateValue(visitor.getScore().intValue());
                    visitorsVo.setGender(userInfo.getSex().name().toLowerCase());
                    visitorsVo.setNickname(userInfo.getNickName());
                    visitorsVo.setTags(StringUtils.split(userInfo.getTags(),","));
                    visitorsVoList.add(visitorsVo);
                    break;
                }
            }
        }
        return visitorsVoList;
    }

    public PageResult queryAlbumList(Integer page, Integer pageSize, Long userId) {
        PageResult pageResult=new PageResult();
        pageResult.setPages(0);
        pageResult.setCounts(0);
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        PageInfo<Publish> pageInfo = this.quanZiApi.queryAlbumList(userId, page, pageSize);
        List<Publish> records = pageInfo.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return pageResult;
        }

        List<Movements>movementsList=new ArrayList<>();
        for (Publish publish : records) {
            Movements movements=new Movements();
            movements.setId(publish.getId().toHexString());
            movements.setImageContent(publish.getMedias().toArray(new String[]{}));
            movements.setTextContent(publish.getText());
            movements.setUserId(publish.getUserId());
            movements.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
            movementsList.add(movements);
        }
        List<Long>userIds=new ArrayList<>();
        for (Movements movements : movementsList) {
            if(!userIds.contains(movements.getUserId())){
                userIds.add(movements.getUserId());
            }
        }
        QueryWrapper<UserInfo>queryWrapper=new QueryWrapper<>();
        queryWrapper.in("user_id",userIds);
        List<UserInfo> userInfos = this.userInfoService.queryUserInfoList(queryWrapper);
        for (Movements movements : movementsList) {
            for (UserInfo userInfo : userInfos) {
                if(movements.getUserId().longValue()==userInfo.getUserId().longValue()){
                    this.fillValueToMovements(movements,userInfo);
                    break;
                }
            }
        }
        pageResult.setItems(movementsList);
        return pageResult;
    }
}
